package com.gzsxy.rabbitmq.producer.config.reliable;

import com.gzsxy.rabbitmq.producer.config.RabbitmqProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 消息可靠队列配置（direct+死信队列）
 * @Author: xiaolong
 * @date: 2023/2/15 13:41
 * @Version: 1.0
 */
@Slf4j
@ConditionalOnProperty(value = "rabbitmq.enable.type", havingValue = "reliable",matchIfMissing = false)
@Configuration
public class ReliableQueueConfig {

    @Autowired
    private RabbitmqProperties config;


    // 声明 zExchange
    @Bean("zExchange")
    public DirectExchange zExchange() {
        return new DirectExchange(config.getExchangeZ());
    }

    // 声明 死信队列交换机
    @Bean("kExchange")
    public DirectExchange kExchange() {
        /**
         * 创建交换器，参数说明：
         * String name：交换器名称
         * boolean durable：设置是否持久化，默认是 false。durable 设置为 true 表示持久化，反之是非持久化。
         * 持久化可以将交换器存盘，在服务器重启的时候不会丢失相关信息。
         * boolean autoDelete：设置是否自动删除，为 true 则设置队列为自动删除，
         */
        return new DirectExchange(config.getDeadLetterExchangeK());
    }

    //声明队列 E 并绑定到对应的死信交换机
    @Bean("queueE")
    public Queue queueE() {
        Map<String, Object> args = new HashMap<>(3);
        //声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", config.getDeadLetterExchangeK());
        //声明当前队列的死信路由 key
        args.put("x-dead-letter-routing-key", "YG");
        /**
         * 创建队列，参数说明：
         * String name：队列名称。
         * boolean durable：设置是否持久化，默认是 false。durable 设置为 true 表示持久化，反之是非持久化。
         * 持久化的队列会存盘，在服务器重启的时候不会丢失相关信息。
         * boolean exclusive：设置是否排他，默认也是 false。为 true 则设置队列为排他。
         * boolean autoDelete：设置是否自动删除，为 true 则设置队列为自动删除，
         * 当没有生产者或者消费者使用此队列，该队列会自动删除。
         * Map<String, Object> arguments：设置队列的其他一些参数。
         */
        return QueueBuilder.durable(config.getQueueE()).withArguments(args).build();
    }

    // 声明队列 E 绑定 Z 交换机
    @Bean
    public Binding queueEBindingZ(@Qualifier("queueE") Queue queueE,
                                  @Qualifier("zExchange") DirectExchange zExchange) {
        return BindingBuilder.bind(queueE).to(zExchange).with("XC");
    }

    //声明队列 F并绑定到对应的死信交换机
        @Bean("queueF")
    public Queue queueF() {
        Map<String, Object> args = new HashMap<>(3);
        //声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", config.getDeadLetterExchangeK());
        //声明当前队列的死信路由 key
        args.put("x-dead-letter-routing-key", "YG");
        return QueueBuilder.durable(config.getQueueF()).withArguments(args).build();
    }

    //声明队列 F 绑定 Z 交换机
    @Bean
    public Binding queueFBindingZ(@Qualifier("queueF") Queue queueF,
                                  @Qualifier("zExchange") DirectExchange zExchange) {
        return BindingBuilder.bind(queueF).to(zExchange).with("XD");
    }

    //声明死信队列 QG
    @Bean("queueG")
    public Queue queueG() {
        return new Queue(config.getDeadLetterQueueG());
    }

    //声明死信队列 QG 绑定关系
    @Bean
    public Binding deadLetterBindingQAD(@Qualifier("queueG") Queue queueG,
                                        @Qualifier("kExchange") DirectExchange kExchange) {
        return BindingBuilder.bind(queueG).to(kExchange).with("YG");
    }
}
